/*
 * @Author: ljk
 * @Date: 2023-05-09 20:57:40
 * @LastEditors: ljk
 * @LastEditTime: 2023-05-10 19:44:07
 * @Description: 
 */
#include <iostream>
#include <cerrno>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <assert.h>

void temin(){

}
int main(){
    //让不同的进程看到同一份资源,任何一种进程间通信中，一定要先让不同的家进程间看到同一份资源    
    int pipefd[2] = {0};
    //1.创建管道

    //通常pipe[0]代表读端，pipe[1]代表写端
    //0->嘴巴->读 1->笔->写
    int n = pipe(pipefd);
    if (n < 0){
        std::cout << "pipe error, " << errno << ":" << strerror(errno) << std::endl;
        return 1;
    }
    std::cout << "pipefd[0]: " << pipefd[0] << std::endl;
    std::cout << "pipefd[1]: " << pipefd[1] << std::endl;
    //2.创建子进程
    pid_t id = fork();
    assert(id != -1);//正常应该用判断,意料之外用if，意料之中用assert
    //子进程
    if (id == 0){
        //3.关闭不需要的fd(建立信道)，让父进程进行读取，让子进程进行写入
        close(pipefd[0]);
        //4.开始通信 -- 结合某种场景
        // const std::string namestr = "hello, I am child";
        // int cnt = 1;
        // char buffer[1024];
        int cnt = 0;
        while (true){
            char x = 'X';
            write(pipefd[1], &x, 1);
            std::cout << "Cnt: " << cnt++ << std::endl;
            sleep(1);

            // snprintf(buffer, sizeof(buffer), "%s, counter: %d, childID: %d\n", namestr.c_str(), cnt++, getpid());
            // write(pipefd[1], buffer, strlen(buffer));
            //sleep(10);
            // sleep(3);
            // break;
        }

        close(pipefd[1]);
        exit(0);
    }

    //父进程
    //3.关闭不需要的fd(建立信道)，让父进程进行读取，让子进程进行写入
    close(pipefd[1]);
    
    //4.开始通信
    char buffer[1024];
    int cnt = 0;
    while (true){
        //sleep(10);
        int n = read(pipefd[0], buffer, sizeof(buffer) - 1);
        if (n > 0){
            buffer[n] == '\0';
            std::cout << "I am father process, child process give me message: " << buffer << std::endl;
        }else if (n == 0){
            std::cout << "I am father process, read end" << std::endl;
            break;
        }else{
            std::cout << "I am father process, read error" << std::endl;
        }
        sleep(1);
        if (cnt++ > 5) break;
    }
    close(pipefd[0]);
    int status = 0;
    waitpid(id, &status, 0);
    std::cout << "sig: " << ((status)&0x7f) << std::endl;
    sleep(100);

    return 0;
}
